﻿namespace DB2WORD.Logics
{
    internal class DragableTree
    {
        public enum Action
        {
            None,
            ChangeGroup,
            ChangeSort,
            ChangeGroupAndSort,
        }

        private TreeView tree = null;
        private TreeNode nodeInDrag = null;
        internal Action<TreeNode, Action> BeforeDrop = null;
        internal Action<TreeNode, Action> AfterDrop = null;

        // 传入一个tree，添加拖放事件
        internal DragableTree(TreeView tree)
        {
            this.tree = tree;
            this.tree.AllowDrop = true;
            this.tree.HideSelection = false;
            this.tree.ItemDrag += TreeView_ItemDrag;
            this.tree.DragDrop += (sender, e) => TreeView_DragDrop(tree, nodeInDrag, e);
            this.tree.DragOver += (sender, e) => TreeView_DragOver(tree, nodeInDrag, e);
            this.tree.DragLeave += (sender, e) => TreeView_Leave(nodeInDrag);
        }

        // 拖动节点
        internal void TreeView_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if(e.Item is TreeNode node)
            {
                nodeInDrag = node;
                tree.DoDragDrop(e.Item, DragDropEffects.Move);
            }
        }

        // 拖动经过
        internal void TreeView_DragOver(TreeView tree, TreeNode nodeInDrag, DragEventArgs e)
        {
            Action action = Action.None;
            // 获取目标位置 -> 目标节点
            Point pointTarget = tree.PointToClient(new Point(e.X, e.Y));
            TreeNode nodeTargrt = tree.GetNodeAt(pointTarget);
            if(nodeTargrt == null
                || nodeTargrt == nodeInDrag
                || nodeTargrt == nodeInDrag.Parent)
            {
                action = Action.None;
            }
            else if(nodeTargrt.Level < nodeInDrag.Level)
            {
                action = Action.ChangeGroup;
            }
            else if(nodeTargrt.Level == nodeInDrag.Level)
            {
                if(nodeTargrt.Parent == nodeInDrag.Parent)
                {
                    action = Action.ChangeSort;
                }
                else
                {
                    action = Action.ChangeGroupAndSort;
                }
            }

            if(action == Action.None)  // 不可放置
            {
                e.Effect = DragDropEffects.None;
                ColorToRed(nodeInDrag);
            }
            else  // 可放置
            {
                e.Effect = DragDropEffects.Move;
                ColorToGray(nodeInDrag);
            }



            //// 获取目标位置 -> 目标节点
            //Point pointTarget = tree.PointToClient(new Point(e.X, e.Y));
            //TreeNode nodeTargrt = tree.GetNodeAt(pointTarget);
            //tree.SelectedNode = nodeTargrt;

            //// 节点是否能放置
            //bool canDrop = true;

            //// 目标节点：存在、不是自身、不是自身的父节点，不是自身的下一个邻居节点
            //if(nodeTargrt == null
            //    || nodeTargrt == nodeInDrag
            //    || nodeTargrt == nodeInDrag.NextNode
            //    || nodeTargrt == nodeInDrag.Parent)
            //{
            //    canDrop = false;
            //}
            ////与移动到低层次节点
            //else if(nodeTargrt.Level < nodeInDrag.Level)
            //{
            //    canDrop = false;
            //}
            //else  // 不可放置
            //{
            //    // 目标节点的父节点：不含自身
            //    TreeNode parentNode = nodeTargrt;
            //    while(parentNode.Parent != null)
            //    {
            //        // 获取父节点
            //        parentNode = parentNode.Parent;

            //        // 父节点是自身，不可放置
            //        if(parentNode == nodeInDrag)
            //        {
            //            canDrop = false;
            //            break;
            //        }
            //    }
            //}

            //if(canDrop)  // 可放置
            //{
            //    e.Effect = DragDropEffects.Move;
            //    ColorToGray(nodeInDrag);
            //}
            //else  // 不可放置
            //{
            //    e.Effect = DragDropEffects.None;
            //    ColorToRad(nodeInDrag);
            //}
        }

        // 拖动放置
        internal void TreeView_DragDrop(TreeView tree, TreeNode nodeInDrag, DragEventArgs e)
        {
            // 获取目标位置 -> 目标节点
            Point pointTarget = tree.PointToClient(new Point(e.X, e.Y));
            TreeNode nodeTargrt = tree.GetNodeAt(pointTarget);
            if(nodeTargrt == null
                || nodeTargrt == nodeInDrag
                || nodeTargrt == nodeInDrag.Parent)
            {
                return;
            }
            Action action = Action.None;
            if(nodeTargrt.Level < nodeInDrag.Level)
            {
                action = Action.ChangeGroup;
            }
            else if(nodeTargrt.Level == nodeInDrag.Level)
            {
                if(nodeTargrt.Parent == nodeInDrag.Parent)
                {
                    action = Action.ChangeSort;
                }
                else
                {
                    action = Action.ChangeGroupAndSort;
                }
            }
            else
            {
                return;
            }

            BeforeDrop?.Invoke(nodeInDrag, action);

            // 清除被移动的节点
            if(nodeInDrag.Parent == null)
                tree.Nodes.Remove(nodeInDrag);
            else
                nodeInDrag.Parent.Nodes.Remove(nodeInDrag);

            //修改分组，放到最后位置
            if(action == Action.ChangeGroup)
            {
                // 添加节点，展开
                nodeTargrt.Nodes.Add(nodeInDrag);
                nodeTargrt.Expand();
            }
            else
            {
                //调整顺序，方法目标节点前面
                var index = this.tree.Nodes.IndexOf(nodeTargrt);
                if(index < 0)
                {
                    var parent = nodeTargrt.Parent;
                    index = parent.Nodes.IndexOf(nodeTargrt);
                    parent.Nodes.Insert(index, nodeInDrag);
                }
                else
                {
                    this.tree.Nodes.Insert(index, nodeInDrag);
                }
            }
            tree.SelectedNode = nodeInDrag;

            AfterDrop?.Invoke(nodeInDrag, action);
            // 恢复颜色
            ColorToDefault(nodeInDrag);
        }

        // 拖动离开：未放置
        private void TreeView_Leave(TreeNode nodeInDrag)
        {
            // 恢复颜色
            ColorToDefault(nodeInDrag);
        }


        // 默认颜色
        internal static void ColorToDefault(TreeNode nodeInDrag)
        {
            nodeInDrag.BackColor = SystemColors.Window;
            nodeInDrag.ForeColor = SystemColors.ControlText;
        }

        // 被拖动的颜色
        internal static void ColorToGray(TreeNode nodeInDrag)
        {
            nodeInDrag.BackColor = Color.LightGray;
            nodeInDrag.ForeColor = SystemColors.ControlText;
        }

        // 被拖动无法放置的颜色
        internal static void ColorToRed(TreeNode nodeInDrag)
        {
            nodeInDrag.BackColor = Color.Pink;
            nodeInDrag.ForeColor = Color.Red;
        }
    }
}
